package com.licode.codekit.buildprj;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.licode.codekit.modal.CreateModal;
import com.licode.codekit.utils.CheckUtil;
import com.licode.codekit.utils.UIBuilderUtil;

import javax.swing.*;
import java.awt.*;
import java.util.Set;

/**
 * @author licode
 */
public class CreateModuleUiBuilder {
    public static int DEFAULT_WID = 460;
    private final JPanel north = new JPanel();
    private final JPanel center = new JPanel();
    private final JLabel prjDir = new JLabel("项目路径：", 4);
    private final JTextField prjDirContent = new JTextField();
    private final JLabel parentArtifactIdName = new JLabel("parent-artifact-id：", 4);
    private final JTextField parentArtifactIdContent = new JTextField();
    private final JLabel parentGroupIdName = new JLabel("parent-group-id：", 4);
    private final JTextField parentGroupIdContent = new JTextField();

    private final JLabel authorName = new JLabel("author：", 4);
    private final JTextField authorContent = new JTextField("licode");

    //------ 新创建模块信息
    private final JLabel groupIdName = new JLabel("group-id：", 4);
    private final JTextField groupIdContent = new JTextField();
    private final JLabel artifactIdName = new JLabel("artifact-id：", 4);
    private final JTextField artifactIdContent = new JTextField();
    private final JLabel version = new JLabel("version：", 4);
    private final JTextField versionContent = new JTextField();
    private final JLabel moduleName = new JLabel("模块名称：", 4);
    private final JTextField moduleNameContent = new JTextField();

    private final JLabel jdkVersionLabel = new JLabel("JDK版本：", 4);
    private final ComboBox<Integer> jdkVersionContent = new ComboBox<>();

    //private final JLabel sbName = new JLabel("Spring Boot：", 4);
    //private final ComboBox<String> sbListContent = new ComboBox<>();

    private final JLabel subModuleList = new JLabel("子模块列表：", 4);
    private final ComboBox<String> subModuleListContent = new ComboBox<>();

    private final JLabel createTypeLabel = new JLabel("模块类型：", 4);
    private final ComboBox<CreateModal> createTypeContent = new ComboBox<>();

    private String createType = CodeKitConf.MT_SINGLE;

    private ProjectContext prjCtx;

    private String addPrjDir;
    private final UIBuilderUtil uiBuilder = new UIBuilderUtil(120);

    public CreateModuleUiBuilder() {
    }

    private String getBasePath() {
        return addPrjDir;
    }

    public JPanel initNorth() {
        JLabel title = new JLabel("小码咨询工程助手");
        title.setFont(new Font("微软雅黑", 0, 16));
        title.setHorizontalAlignment(2);
        title.setVerticalAlignment(0);
        // this.north.add(null);
        return this.north;
    }

    private void intiProjectContext(String dir) {
        String filePath = dir + "\\pom.xml";
        prjCtx = new ProjectContext(CodeKitConf.MODULE_TYPE);
        prjCtx.parse(filePath);
        prjCtx.setRootDir(dir);
        prjCtx.setCurrentDir(dir);
    }

    public JComponent initCenter(Project rootPrj, String addPrjDir, DialogWrapper dialogWrapper) {
        int defWidth = 530;
        GridLayout layGrid = new GridLayout(0, 1);

        intiProjectContext(addPrjDir);

        layGrid.setHgap(16);
        this.center.setLayout(layGrid);

        this.addPrjDir = addPrjDir;

        this.prjDirContent.setPreferredSize(new Dimension(DEFAULT_WID, 0));

        this.center.add(this.buildRow(this.prjDir, this.prjDirContent, defWidth));
        this.center.add(this.buildRow(this.parentGroupIdName, this.parentGroupIdContent, defWidth));
        this.center.add(this.buildRow(this.parentArtifactIdName, this.parentArtifactIdContent, defWidth));
        this.center.add(this.buildRow(this.jdkVersionLabel, this.jdkVersionContent, defWidth));
        //this.center.add(this.buildRow(this.sbName, this.sbListContent, defWidth));
        this.center.add(this.buildRow(this.subModuleList, this.subModuleListContent, defWidth));

        this.center.add(this.buildRow(this.authorName, this.authorContent, defWidth));

        this.center.add(this.buildRow(this.groupIdName, this.groupIdContent, defWidth));
        this.center.add(this.buildRow(this.artifactIdName, this.artifactIdContent, defWidth));
        this.center.add(this.buildRow(this.version, this.versionContent, defWidth));
        this.center.add(this.buildRow(this.moduleName, this.moduleNameContent, defWidth));

        this.center.add(this.initBottom(rootPrj, dialogWrapper));

        authorContent.setText(prjCtx.getConfig().getAuthor());

        // mdListContent.addItemListener(e -> moduleNameContent.setText(e.getItem().toString()));

        initModuleInfo();

        return this.center;
    }

    private void initModuleInfo() {
        this.prjDirContent.setText(prjCtx.getRootDir());

        this.parentGroupIdContent.setText(prjCtx.getParentGroupId());
        this.parentArtifactIdContent.setText(prjCtx.getParentArtifactId());

        this.groupIdContent.setText(prjCtx.getGroupId());
        this.artifactIdContent.setText(prjCtx.getArtifactId());
        this.moduleNameContent.setText(prjCtx.getModuleName());
        this.versionContent.setText(prjCtx.getVersion());

        this.prjDirContent.setEditable(false);
        this.parentGroupIdContent.setEditable(false);
        this.parentArtifactIdContent.setEditable(false);

        this.initModuleComBox();
    }

    private void initModuleComBox() {
        if (null != prjCtx && null != this.prjCtx.getModules()) {
            Set<String> subModuleNames = this.prjCtx.getModules();
            subModuleNames.forEach(subModuleListContent::addItem);
        }

        jdkVersionContent.setEditable(false);
        jdkVersionContent.addItem(8);
        jdkVersionContent.addItem(17);
        jdkVersionContent.addItem(21);

        if (17 == prjCtx.getJdkVersion()) {
            jdkVersionContent.setSelectedIndex(1);
        } else if (21 == prjCtx.getJdkVersion()) {
            jdkVersionContent.setSelectedIndex(2);
        } else {
            jdkVersionContent.setSelectedIndex(0);
        }

        createTypeContent.setEditable(false);
        /*createTypeContent.addItem(new CreateModal("默认", CodeKitConf.BM_DEFAULT));
        createTypeContent.addItem(new CreateModal("六边形", CodeKitConf.BM_DOMAIN));
        createTypeContent.addItem(new CreateModal("单组件", CodeKitConf.BM_COMPONENT));
        createTypeContent.addItem(new CreateModal("应用", CodeKitConf.BM_STARTER));
        createTypeContent.addItem(new CreateModal("父模块", CodeKitConf.BM_PARENT));
        createTypeContent.setSelectedIndex(0);*/

        createTypeContent.addItem(new CreateModal("组件", CodeKitConf.MT_SINGLE));
        createTypeContent.addItem(new CreateModal("应用", CodeKitConf.MT_STARTER));
        createTypeContent.addItem(new CreateModal("单模块(简单)", CodeKitConf.MT_SIMPLE_ARCH));
        createTypeContent.addItem(new CreateModal("单模块(领域)", CodeKitConf.MT_SINGLE_SIX));
        createTypeContent.addItem(new CreateModal("多模块(领域)", CodeKitConf.MT_SPEC_SIX));
        createTypeContent.addItem(new CreateModal("模块(父级)", CodeKitConf.MT_PARENT));
        // createTypeContent.addItem(new CreateModal("父模块", CodeKitConf.MT_PROJECT));
        createTypeContent.setSelectedIndex(0);

        createTypeContent.addItemListener(e -> {
            if (e.getItem() instanceof CreateModal) {
                createType = ((CreateModal)e.getItem()).getType();
            }
        });

        jdkVersionContent.addItemListener(e -> {
            if (e.getItem() instanceof Integer) {
                prjCtx.setJdkVersion((Integer)e.getItem());
            }
        });
    }

    private String getTemplateFile() {
        if (CodeKitConf.BM_DEFAULT.equals(createType)) {
            return "module.zip";
        } if (CodeKitConf.BM_DOMAIN.equals(createType)) {
            return "do-module.zip";
        } else if (CodeKitConf.BM_PARENT.equals(createType)) {
            return "parent-module.zip";
        } else if (CodeKitConf.BM_STARTER.equals(createType)) {
            return "one-starter.zip";
        } else if (CodeKitConf.BM_COMPONENT.equals(createType)) {
            return "one-module.zip";
        } else {
            return "";
        }
    }

    private void addModule(Project rootPrj, DialogWrapper dialogWrapper, String templateFile) {
        String pDir = this.prjDirContent.getText();
        String artifactId = this.artifactIdContent.getText();
        String groupId = this.groupIdContent.getText().trim();
        String moduleName = this.moduleNameContent.getText().trim();
        String version = this.versionContent.getText().trim();

        if (null == prjCtx) {
            Messages.showMessageDialog(rootPrj, "当前工程信息解析错误",
                    "温馨提示", Messages.getInformationIcon());
            return;
        }

        if (!prjCtx.canAddModule()) {
            Messages.showMessageDialog(rootPrj, "工程类型错误",
                    "温馨提示", Messages.getInformationIcon());
            return;
        }

        if (StringUtil.isEmpty(moduleName)) {
            moduleName = artifactId;
        }

        if (StringUtil.isEmpty(pDir)) {
            Messages.showMessageDialog(rootPrj, "请输入工程目录！",
                    "温馨提示", Messages.getInformationIcon());
        } else if (StringUtil.isEmpty(artifactId)) {
            Messages.showMessageDialog(rootPrj, "请输入artifact-id！",
                    "温馨提示", Messages.getInformationIcon());
        } else if (StringUtil.isEmpty(groupId)) {
            Messages.showMessageDialog(rootPrj, "请输入group-id！",
                    "温馨提示", Messages.getInformationIcon());
        }  else if (!CheckUtil.checkGroupId(groupId)) {
            Messages.showMessageDialog(rootPrj, "请输入合法group-id！",
                    "温馨提示", Messages.getInformationIcon());
        } else if (StringUtil.isEmpty(moduleName)) {
            Messages.showMessageDialog(rootPrj, "请输入模块名称！",
                    "温馨提示", Messages.getInformationIcon());
        } else if (!CheckUtil.checkStr(moduleName)) {
            Messages.showMessageDialog(rootPrj, "请输入合法的模块名称！",
                    "温馨提示", Messages.getInformationIcon());
        } else if (StringUtil.isEmpty(version)) {
            Messages.showMessageDialog(rootPrj, "请输入模块版本号！",
                    "温馨提示", Messages.getInformationIcon());
        } else {
            prjCtx.setModuleName(moduleName);
            prjCtx.setGroupId(groupId);
            prjCtx.setArtifactId(artifactId);
            prjCtx.setVersion(version);

            try {
                ModuleBuilder moduleBuilder = new ModuleBuilder();
                if (moduleBuilder.buildModule(prjCtx, createType)) {
                // if (this.pb.createModule(rootPrj, prjCtx, templateFile)) {
                    Messages.showMessageDialog(rootPrj, "增加模块成功",
                            "温馨提示", Messages.getInformationIcon());
                    dialogWrapper.close(0);
                }
            } catch (Exception ignore) {
                Messages.showMessageDialog(rootPrj, "增加模块失败",
                        "温馨提示", Messages.getInformationIcon());
            }
        }
    }

    private JComponent buildRow(Component left, Component right, int rWidth) {
        right.setMinimumSize(new Dimension(rWidth, 0));
        return uiBuilder.buildFillRow(left, right);
    }

    private JButton buildButton(String text) {
        JButton submit = new JButton(text);
        submit.setHorizontalAlignment(0);
        submit.setVerticalAlignment(0);
        return submit;
    }

    public JComponent initBottom(Project rootPrj, DialogWrapper dialogWrapper) {
        JButton submit = this.buildButton("新增模块");
        JButton cancel = this.buildButton("关闭");
        FlowLayout fl = new FlowLayout();
        JPanel panel = new JPanel(fl);
        fl.setAlignment(2);
        panel.add(createTypeLabel);
        panel.add(createTypeContent);
        panel.add(submit);
        panel.add(cancel);
        submit.addActionListener((e) -> {
            this.addModule(rootPrj, dialogWrapper, getTemplateFile());
        });
        cancel.addActionListener((e) -> {
            dialogWrapper.close(0);
        });

        return panel;
    }
}
